home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Belgian Amiga Club - ADF Collection
/
BS1 part 41.zip
/
BS1 part 41
/
Amiga Plus 1.adf
/
Programming
/
ExecPrt.asm
< prev
next >
Wrap
Assembly Source File
|
1978-04-08
|
9KB
|
243 lines
;EXECPRT.ASM 12/09/88
;COPYRIGHT 1988 BY DANIEL WOLF PH.D.
;EXEC I/O EXAMPLE FOR PRINTER OUTPUT
;USES DEVICE-BASED I/O WITH IOBLOCK AND REPLY MSGPORT
SIZE.STDIO EQU $30
SIZE.MP EQU $22
CMD_WRITE EQU $3
LVO.ALLOCMEM EQU $FFFFFF3A
LVO.ADDPORT EQU $FFFFFE9E
LVO.FINDTASK EQU $FFFFFEDA
LVO.FREEMEM EQU $FFFFFF2E
LVO.GETMSG EQU $FFFFFE8C
LVO.WAITPORT EQU $FFFFFE80
LVO.DOIO EQU $FFFFFE38
LVO.CHECKIO EQU $FFFFFE2C
LVO.ABORTIO EQU $FFFFFE20
LVO.SENDIO EQU $FFFFFE32
LVO.WAITIO EQU $FFFFFE26
LVO.OPENDEVICE EQU $FFFFFE44
LVO.FREESIGNAL EQU $FFFFFEB0
LVO.CLOSEDEVICE EQU $FFFFFE3E
LVO.ALLOCSIGNAL EQU $FFFFFEB6
IO.COMMAND EQU $1C
IO.DEVICE EQU $14
IO.DATA EQU $28
IO.LENGTH EQU $24
LIST.HEAD EQU $0
LIST.TAIL EQU $4
MEMF_PUBLIC EQU $0
MEMF_CLEAR EQU $10000
MP.MSGLIST EQU $14
MP.SIGTASK EQU $10
MP.SIGBIT EQU $F
MP.FLAGS EQU $E
MSG.REPLYPORT EQU $E
NODE.PRED EQU $4
NODE.NAME EQU $A
NODE.TYPE EQU $8
NODE.PRI EQU $9
NT_MSGPORT EQU $4
NT_MESSAGE EQU $5
PA_SIGNAL EQU $0
MAIN
BSR OPENPRINTER ;SET UP REPLY MSGPORT, SIGBIT, IOBLOCK THEN OPEN IT
TST.L D0 ;IF PRINTER OPENING FAILED THEN
BNE ERROR ; BRANCH OUT OF HERE
MOVE.L IOREQ,A1 ;ELSE SET UP POINTERS TO IOBLOCK AND ASCII TEXT
LEA IOTEXT,A0
BSR PRINTERWRITE ;CALL PRINTER OUTPUT ROUTINE
; MOVE.L #18000,D0 ;A VERY DUMB DELAY LOOP TO WASTE SOME TIME
;LOOP ;IF YOU CHANGE PRINTERWRITE TO USE SENDIO.
; MOVE.L A0,-(SP) ;DOIO DOESN'T NEED THIS BECAUSE IT WAITS TIL I/O DONE.
; MOVE.L (SP)+,A0 ;WITHOUT THIS DELAY, ABORTIO (IN CLOSEPRINTER)
; DBRA D0,LOOP ;HAPPENS IMMEDIATELY - TOO FAST FOR SENDIO TO FINISH
BSR CLOSEPRINTER ;FREE ALL RESOURCES ASSOCIATED WITH PRINTER DEVICE
MOVEQ #0,D0
ERROR ;AND WAVE GOODBYE
RTS
;**************** APPROPRIATE EXEC AND I/O MACROS
NEWLIST MACRO ;An
MOVE.L \1,(\1) ;MOVE An TO (An)
MOVE.L \1,LIST.HEAD(\1) ;SHUFFLE HEAD AND TAIL POINTERS
ADD.L #LIST.TAIL,LIST.HEAD(\1)
CLR.L LIST.TAIL(\1)
MOVE.L \1,LIST.TAIL+NODE.PRED(\1) ;SO THIS PORT IS FIRST IN LIST
ENDM
OPENDEVICE MACRO ;*NAME,UNIT,*IOREQUEST,FLAGS
LEA \1,A0 ;PUT NAME POINTER INTO A0
MOVE.L #\2,D0 ;PUT UNIT NUMBER INTO D0
MOVE.L \3,A1 ;PUT IOREQ POINTER INTO A1
MOVE.L #\4,D1 ;PUT IOREQ FLAGS INTO D1
SYSCALL OPENDEVICE ;NOW MAKE THE CALL
ENDM
CLOSEDEVICE MACRO ;*IOREQUEST ;SET UP TO CLOSE A DEVICE
MOVE.L \1,A1 ;PUT IOREQ POINTER INTO A1
SYSCALL CLOSEDEVICE ;NOW MAKE THE CALL
ENDM
;*************** AND A FEW SIMPLE PROGRAMMING MACROS
SYSCALL MACRO ;CALL A EXEC LIBRARY ROUTINE
MOVE.L 4,A6
JSR LVO.\1(A6)
ENDM
CALL MACRO ;CALL A KERNEL ROUTINE
JSR LVO.\1(A6)
ENDM
PUSH MACRO ;PUSH A REGISTER ONTO STACK
MOVEM.L \1,-(SP)
ENDM
PULL MACRO ;PULL A REGISTER FROM STACK
MOVEM.L (SP)+,\1
ENDM
PUBLICMEM MACRO ;SIZE ;ALLOCATE SOME PUBLIC MEMORY
MOVE.L #MEMF_PUBLIC!MEMF_CLEAR,D1
MOVE.L \1,D0
SYSCALL ALLOCMEM
ENDM
;*************** GENERAL PURPOSE CREATE AND DELETE MSGPORT ROUTINES
MAKEAPORT ;ENTER W/ PTR TO NAME IN A0, PRIORITY IN D0
PUSH D0/A0 ;STASH THE REGS
MOVE #-1,D0 ;DON'T CARE WHICH SIGBIT ALLOCATED FOR PORT
SYSCALL ALLOCSIGNAL ;GET A SIGBIT
MOVE.B D0,D7 ;STASH SIGBIT IN D7
CMPI.B #-1,D0 ;IF ERROR -
BEQ ERR_PORT ; BRANCH OUT FROM HERE
PUBLICMEM #SIZE.MP ;ELSE ALLOCATE MEM FOR A MESSAGE PORT
TST.L D0 ;IF ERROR -
BEQ.S ERR_PORT ; BRANCH OUT FROM HERE
MOVE.L D0,A4 ;ELSE PUT POINTER TO ALLOCATED MEM IN A4
MOVEQ #0,D0
MOVE.L D0,A1 ;FOR THIS TASK -
CALL FINDTASK ;FIND THE TASK CONTROL BLOCK
MOVE.L D0,MP.SIGTASK(A4) ;TELL PORT WHERE THE TCB IS
PULL D0/A0 ;RESTORE THE REGS
MOVE.L A0,NODE.NAME(A4) ;TELL LISTNODE OF PORT ITS NAME
MOVE.B D0,NODE.PRI(A4) ;TELL LISTNODE OF PORT ITS PRIORITY
MOVE.B #NT_MSGPORT,NODE.TYPE(A4) ;TELL LISTNODE OF PORT ITS TYPE
MOVE.B #PA_SIGNAL,MP.FLAGS(A4) ;TELL PORT ITS FLAGS
MOVE.B D7,MP.SIGBIT(A4) ;TELL PORT WHICH SIGBIT WAS ASSIGNED TO IT
CMPA.L #0,A0 ;IF NO NAME
BEQ.S PRIVATEPORT ; THEN ITS A PRIVATE PORT
PUBLICPORT ;ELSE IT HAS A NAME AND ITS PUBLIC
MOVE.L A4,A1 ;PUT PTR TO MEM OF PORT INTO A1
CALL ADDPORT ;AND ADD THIS PORT TO EXISTING ONES
BRA NOPORTERR ;AND FINISH UP
PRIVATEPORT
LEA MP.MSGLIST(A4),A0 ;SET UP PORT AS FIRST IN LIST
NEWLIST A0 ;SEE MACRO ABOVE
NOPORTERR
MOVE.L A4,D0 ;PUT ADDRESS OF MSGPORT IN D0
RTS
ERR_PORT ;IF ERROR, SET D0 = 0
MOVEQ #0,D0
RTS
KILLAPORT ;ENTER W/ POINTER TO MSGPORT IN A0
PUSH A0 ;STASH THE POINTER ON THE STACK
MOVEQ #0,D0
MOVE.B MP.SIGBIT(A0),D0 ;AND FREE UP THE SIGNAL BIT
CALL FREESIGNAL ;PREVIOUSLY ALLOCATED FOR THIS PORT
PULL A1 ;AND THE PORT'S MEMORY
MOVE.L #SIZE.MP,D0
SYSCALL FREEMEM
RTS
;**************** PRINTER DEVICE SUPPORT CODE
OPENPRINTER
MOVEQ #0,D0 ;SET NAME AND PRIORITY OF MSGPORT = 0
MOVE.L D0,A0
BSR MAKEAPORT ;AND CREATE REPLY MSGPORT FOR PRINTER I/O BLOCK
TST.L D0
BEQ ERR_OPENPRT
MOVE.L D0,PMPORT ;ELSE THIS IS ADDR OF PRINTER MSGPORT
BSR CREATEPRTIO ;USE MSGPORT TO HELP SET UP AN IOBLOCK
TST.L D0 ;IF IOBLOCK BAD THEN
BEQ ERR_OPENPRT ; BRANCH OUT FROM HERE
MOVE.L PRTBUF,IO.DATA(A0) ;ELSE ATTACH BUFFER TO IOBLOCK
MOVE.L #-1,IO.LENGTH(A0) ;AND SET ARBITRARY LENGTH I/O
OPENPRT
OPENDEVICE DEVNAME,0,IOREQ,0 ;NOW ATTACH PRINTER DEVICE TO IOBLOCK
TST.L D0 ;IF NO PROBLEM THEN
BEQ.S END_OPENPRT ; BRANCH TO END WITH D0 = 0
ERR_OPENPRT
MOVE.L #1,D0 ;ELSE FAIL WITH D0 = 1
END_OPENPRT
RTS
CREATEPRTIO
PUBLICMEM #SIZE.STDIO ;GET SOME MEM FOR AN IOBLOCK
TST.L D0 ;IF UNSUCCESSFUL THEN
BEQ ERR_PRTIO ; BRANCH OUT FROM HERE W/ D0 = 0
MOVE.L D0,IOREQ ;ELSE D0 = PTR TO IOBLOCK
MOVE.L D0,A0
MOVE.B #NT_MESSAGE,NODE.TYPE(A0) ;SET ITS LISTNODE TYPE = 'MESSAGE'
MOVE.B #0,NODE.PRI(A0) ;SET ITS LISTNODE PRIORITY = 0
MOVE.L PMPORT,MSG.REPLYPORT(A0) ;SET ITS REPLYPORT = MSGPORT
ERR_PRTIO
RTS ;EXIT W/ D0 = ADDR OF IOBLOCK (0 IF ERROR)
CLOSEPRINTER
MOVE.L IOREQ,A1 ;GET ADDRESS OF IOBLOCK
CALL CHECKIO ;SEE IF I/O DONE
TST.L D0 ;IF DONE THEN
BNE CLOSEPRT ; BRANCH OUT OF HERE
MOVE.L IOREQ,A1 ;ELSE GET ADDRESS OF IOBLOCK
CALL ABORTIO ;AND FORCE I/O TO END
MOVE.L PMPORT,A0 ;NOW WAIT FOR A MESSAGE AT THE REPLY PORT
CALL WAITPORT
MOVE.L PMPORT,A0
CALL GETMSG ;GET MESSAGE FROM PORT SAYING I/O ABORTED
CLOSEPRT
CLOSEDEVICE IOREQ ;NOW CLOSE DEVICE ATTACHED TO THE IOBLOCK
MOVE.L PMPORT,A0
BSR KILLAPORT ;AND FREE MSGPORT'S SIG BIT AND MEMORY
MOVE.L IOREQ,A1 ;AND THE IOBLOCK'S MEMORY, TOO!
MOVE.L #SIZE.STDIO,D0
SYSCALL FREEMEM
RTS
PRINTERWRITE ;ENTER W/ PTR TO IOBLOCK IN A1
; W/ PTR TO NULL-TERMINATED ASCII IN A0
MOVE #CMD_WRITE,IO.COMMAND(A1) ;PUT 'WRITE' INTO IOBLOCK COMMAND FIELD
MOVE.L A0,IO.DATA(A1) ;PTR TO NULL-TERMINATED DATA
MOVE.L #-1,IO.LENGTH(A1) ;#BYTES TO WRITE (-1 MEANS UNTIL A NULL)
CALL DOIO ;AND CALL THE I/O ROUTINE (TRY SENDIO HERE)
RTS
DATA
PMPORT DC.L 0 ;PTR TO IOBLOCK REPLY MSGPORT
IOREQ DC.L 0 ;PTR TO PRINTER IOBLOCK
PRTBUF DS.B 16 ;ABSOLUTELY NECESSARY LITTLE BUFFER
DEVNAME
DC.B 'printer.device',0 ;NAME OF PRINTER DEVICE
EVEN
IOTEXT
DC.B 10,'Hello from the heart of Amiga Exec',13,10,0
EVEN
END